using System;

namespace JustinAngel.MindwaveSensor.WP8
{
    /// <summary>
    /// Represents a single reading from the Mindwave Mobile headset. 
    /// </summary>
    public class MindwaveReading
    {
        /// <summary>
        /// Initializes a new instance of the MindwaveReading class. 
        /// </summary>
        /// <remarks>
        /// Empty c'tor only available for testing and serialization. 
        /// </remarks>
        public MindwaveReading()
        {
        }

        /// <summary>
        /// Helper c'tor with properties. 
        /// </summary>
        internal MindwaveReading(int quality, int delta, int theta,
                            int alphaLow, int alphaHigh, int betaLow, int betaHigh,
                            int gammaLow, int gammaMid, int eSenseAttention,
                            int eSenseMeditation, DateTime timestamp)
        {
            Quality = quality;
            Delta = delta;
            Theta = theta;
            AlphaLow = alphaLow;
            AlphaHigh = alphaHigh;
            BetaLow = betaLow;
            BetaHigh = betaHigh;
            GammaLow = gammaLow;
            GammaMid = gammaMid;
            this.eSenseAttention = eSenseAttention;
            this.eSenseMeditation = eSenseMeditation;
            Timestamp = timestamp;
        }

        /// <summary>
        /// Gets the quality level of the current reading on a descending scale.
        /// </summary>
        /// <remarks>
        /// 1. The lower this number the higher quality the data is. 
        /// 2. The number 0 represents high-quality data and anything above that isn't necessairly usable. 
        /// 3. It's best to use the IsDataReliable for data validation.  
        /// 4. This property values are ranged between 0 and 200. 
        /// </remarks>
        public int Quality { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a Delta (0.5 - 2.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int Delta { get; set; }

        /// <summary>
        /// Gets an Int24 representing a Theta (3.5 - 6.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int Theta { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a Low Alpha (7.5 - 9.25Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int AlphaLow { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a High Alpha (10 - 11.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int AlphaHigh { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a Low Beta (13 - 16.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int BetaLow { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a High Beta (18 - 29.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int BetaHigh { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a Low Gamma (31 - 39.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int GammaLow { get; private set; }

        /// <summary>
        /// Gets an Int24 representing a Mid Gamma (41 - 49.75Hz) wavelangth EEG reading. 
        /// </summary>
        /// <remarks>
        /// This power spectrum bands are computed using FFT distribution.
        /// Which means that this number cannot be used to correlate to a Hz/sec value. 
        /// The only purpose of this value is when compared to previous or future readings. 
        /// </remarks>
        public int GammaMid { get; private set; }

        /// <summary>
        /// Gets an ascending value between 0 and 100 indicating how "attentive" the user is. 
        /// </summary>
        /// <remarks>
        /// The higher the number the higher the eSense Attention score is. 
        /// Mindwave apps use the range of 70 to 100 to indicate the user is attentive. 
        /// </remarks>
        public int eSenseAttention { get; private set; }

        /// <summary>
        /// Gets an ascending value between 0 and 100 indicating how "meditative" the user is. 
        /// </summary>
        /// <remarks>
        /// The higher the number the higher the eSense Meditation score is. 
        /// Mindwave apps use the range of 70 to 100 to indicate the user is meditative. 
        /// </remarks>
        public int eSenseMeditation { get; private set; }

        public override string ToString()
        {
            return string.Format(@"Quality: {0}, Delta: {1}, Theta: {2}, AlphaLow: {3}, AlphaHigh: {4}, BetaLow: {5}, BetaHigh: {6}, GammaLow: {7}, GammaMid: {8}, eSenseAttention: {9}, eSenseMeditation: {10}", Quality, Delta, Theta, AlphaLow, AlphaHigh, BetaLow, BetaHigh, GammaLow, GammaMid, eSenseAttention, eSenseMeditation);
        }

        /// <summary>
        /// Gets the time when this reading was read off the sensor. 
        /// </summary>
        public DateTime Timestamp { get; private set; }

        /// <summary>
        /// Gets a value indicating whether this is high-quality data. 
        /// </summary>
        public bool IsDataReliable
        {
            get
            {
                return Quality == 0;
            }
        }
    }
}